// Copyright 2022 jeff.li. and/or its affiliates.

#include <gtest/gtest.h>
#include <tbir/runtime/builtins_modules/_longobject.h>

namespace tbir::runtime {

    TEST(PythonBuiltins, longobject_fast_mod) {
        EXPECT_EQ(py_builtins::fast_mod(5, 3), 2);
        EXPECT_EQ(py_builtins::fast_mod(5, -3), -1);
        EXPECT_EQ(py_builtins::fast_mod(-5, 3), 1);
        EXPECT_EQ(py_builtins::fast_mod(-5, -3), -2);

        EXPECT_EQ(py_builtins::fast_mod(5ULL, 3), 2);
        EXPECT_EQ(py_builtins::fast_mod(5ULL, -3), -1);
        EXPECT_EQ(py_builtins::fast_mod(-5, 3ULL), 1);
        EXPECT_EQ(py_builtins::fast_mod(5, 3ULL), 2);
        EXPECT_EQ(py_builtins::fast_mod(5ULL, 3ULL), 2);

        EXPECT_EQ(py_builtins::fast_mod(INT64_MIN, 3), 1);
        EXPECT_EQ(py_builtins::fast_mod(INT64_MIN, -3), -2);
        EXPECT_EQ(py_builtins::fast_mod(INT64_MIN, INT64_MIN), 0);
        EXPECT_EQ(py_builtins::fast_mod(INT64_MIN, INT64_MAX), INT64_MAX - 1);

        EXPECT_EQ(py_builtins::fast_mod(INT64_MAX, 3), 1);
        EXPECT_EQ(py_builtins::fast_mod(INT64_MAX, -3), -2);
        EXPECT_EQ(py_builtins::fast_mod(INT64_MAX, INT64_MAX), 0);
        EXPECT_EQ(py_builtins::fast_mod(INT64_MAX, INT64_MIN), -1);

        EXPECT_EQ(py_builtins::fast_mod(0, 3), 0);
        EXPECT_EQ(py_builtins::fast_mod(0, -3), 0);
        EXPECT_EQ(py_builtins::fast_mod(0, INT64_MIN), 0);
        EXPECT_EQ(py_builtins::fast_mod(0, INT64_MAX), 0);
        EXPECT_EQ(py_builtins::fast_mod(0, UINT64_MAX), 0);

        EXPECT_EQ(py_builtins::fast_mod(UINT64_MAX, 3), 0);
        EXPECT_EQ(py_builtins::fast_mod(UINT64_MAX, -3), 0);
        EXPECT_EQ(py_builtins::fast_mod(UINT64_MAX, UINT64_MAX), 0);
        EXPECT_EQ(py_builtins::fast_mod(UINT64_MAX, INT64_MAX), 1);
        EXPECT_EQ(py_builtins::fast_mod(UINT64_MAX, INT64_MIN), -1);
        EXPECT_EQ(py_builtins::fast_mod(UINT64_MAX, -INT64_MAX), -INT64_MAX + 1);
    }

    TEST(PythonBuiltins, longobject_fast_floor_div) {
        EXPECT_EQ(py_builtins::fast_floor_div(5, 3), 1);
        EXPECT_EQ(py_builtins::fast_floor_div(5, -3), -2);
        EXPECT_EQ(py_builtins::fast_floor_div(-5, 3), -2);
        EXPECT_EQ(py_builtins::fast_floor_div(-5, -3), 1);

        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MIN, 3), -3074457345618258603LL);
        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MIN, -3), 3074457345618258602LL);
        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MIN, INT64_MIN), 1);
        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MIN, INT64_MAX), -2);

        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MAX, 3), 3074457345618258602LL);
        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MAX, -3), -3074457345618258603LL);
        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MAX, INT64_MAX), 1);
        EXPECT_EQ(py_builtins::fast_floor_div(INT64_MAX, INT64_MIN), -1);

        EXPECT_EQ(py_builtins::fast_floor_div(0, 3), 0);
        EXPECT_EQ(py_builtins::fast_floor_div(0, -3), 0);
        EXPECT_EQ(py_builtins::fast_floor_div(0, INT64_MIN), 0);
        EXPECT_EQ(py_builtins::fast_floor_div(0, INT64_MAX), 0);
        EXPECT_EQ(py_builtins::fast_floor_div(0, UINT64_MAX), 0);
    }

}  // namespace tbir::runtime
